import { useEffect, useRef, useState } from 'react'
import LanguageSelector from './components/LanguageSelector';
import Progress from './components/Progress';

import './App.css'

function App() {
  // useState定义的变量是响应式的，当状态改变时会触发组件的重新渲染


  // 加载大模型
  const [ready, setReady] = useState(null);
  const [disabled, setDisabled] = useState(false);
  const [progressItems, setProgressItems] = useState([]);

  // 输入和输出框
  const [input, setInput] = useState('what is your name?');
  const [sourceLanguage, setSourceLanguage] = useState('eng_Latn');
  const [targetLanguage, setTargetLanguage] = useState('fra_Latn');
  const [output, setOutput] = useState('');

  // 创建一个工作线程对象
  const worker = useRef(null);

  // 一旦App组件被挂载，就使用useEffect钩子来设置worker ，类似于vue的mounted生命周期
  useEffect(() => {

    if (!worker.current) {
      // 如果不存在的话则创建一个工作线程
      worker.current = new Worker(new URL('./worker.js', import.meta.url), {
        type: 'module'
      });
    }

    // 为来自工作线程的消息创建回调函数。
    const onMessageReceived = (e) => {
      switch (e.data.status) {
        case 'initiate':
          // 模型文件开始加载:向列表中添加一个新的进度项。
          setReady(false);
          setProgressItems(prev => [...prev, e.data]);
          break;

        case 'progress':
          // 模型文件进度:更新其中一个进度项。
          setProgressItems(
            prev => prev.map(item => {
              if (item.file === e.data.file) {
                return { ...item, progress: e.data.progress }
              }
              return item;
            })
          );
          break;

        case 'done':
          // 模型文件加载:从列表中删除进度项。
          setProgressItems(
            prev => prev.filter(item => item.file !== e.data.file)
          );
          break;

        case 'ready':
          // 管道就绪:工作线程已经准备好接受消息。
          setReady(true);
          break;

        case 'update':
          // 生成更新:更新输出文本。
          setOutput(e.data.output);
          break;

        case 'complete':
          // 生成完成:重新启用“翻译”按钮
          setDisabled(false);
          break;
      }
    };

    // 添加事件监听器，当Web Worker发送消息时触发回调函数
    worker.current.addEventListener('message', onMessageReceived);

    // 定义组件卸载时的清理函数。
    return () => worker.current.removeEventListener('message', onMessageReceived);

  });

  const translate = () => {
    setDisabled(true);
    worker.current.postMessage({
      text: input,
      src_lang: sourceLanguage,
      tgt_lang: targetLanguage,
    });
  }

  return (
    <>
      <h1>AI翻译</h1>
      <h2>基于Transformers的多语言翻译</h2>

      <div className='container'>

        <div className='language-container'>
          <LanguageSelector type={"Source"} defaultLanguage={"eng_Latn"} onChange={x => setSourceLanguage(x.target.value)} />
          <LanguageSelector type={"Target"} defaultLanguage={"fra_Latn"} onChange={x => setTargetLanguage(x.target.value)} />
        </div>

        <div className='textbox-container'>
          <textarea value={input} rows={3} onChange={e => setInput(e.target.value)}></textarea>
          <textarea value={output} rows={3} readOnly></textarea>
        </div>

      </div>

      <button disabled={disabled} onClick={translate}>翻译</button>

      <div className='progress-bars-container'>
        {ready === false && (
          <label>加载模型中,请稍等....</label>
        )}
        {progressItems.map(data => (
          <div key={data.file}>
            <Progress text={data.file} percentage={data.progress} />
          </div>
        ))}
      </div>

    </>
  )

}

export default App
